/**
 * Copyright (C) 2011 PROCESSBASE PROCESSBASE Ltd This library is free software;
 * you can redistribute it and/or modify it under the terms of the GNU Lesser
 * General Public License as published by the Free Software Foundation version
 * 2.1 of the License. This library is distributed in the hope that it will be
 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
 * General Public License for more details. You should have received a copy of
 * the GNU Lesser General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>
 */
package org.processbase.bonita.services.impl;

import com.liferay.portal.kernel.repository.model.FileEntry;
import com.liferay.portlet.documentlibrary.model.DLFileEntry;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import org.ow2.bonita.facade.exception.DocumentAlreadyExistsException;
import org.ow2.bonita.facade.exception.DocumentNotFoundException;
import org.ow2.bonita.facade.exception.DocumentationCreationException;
import org.ow2.bonita.facade.impl.SearchResult;
import org.ow2.bonita.facade.uuid.ProcessDefinitionUUID;
import org.ow2.bonita.facade.uuid.ProcessInstanceUUID;
import org.ow2.bonita.search.DocumentCriterion;
import org.ow2.bonita.search.DocumentSearchBuilder;
import org.ow2.bonita.search.index.DocumentIndex;
import org.ow2.bonita.services.Document;
import org.ow2.bonita.services.DocumentationManager;
import org.ow2.bonita.services.impl.DocumentImpl;

/**
 *
 * @author marat
 */
public class LiferayDocumentationManager implements DocumentationManager {

    private LiferayDocumentLibrary documentLibrary;

    public LiferayDocumentationManager(final String companyMx, final String group, final String user) {
        try {
//            System.out.println("company = " + company);
//            System.out.println("group = " + group);
//            System.out.println("user = " + user);
            documentLibrary = new LiferayDocumentLibrary(companyMx, group, user);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    @Override
    public Document createDocument(String name, ProcessDefinitionUUID definitionUUID, ProcessInstanceUUID instanceUUID, String fileName, String contentMimeType, byte[] fileContent) throws DocumentationCreationException, DocumentAlreadyExistsException {
//        System.out.println("createDocument2");
//        System.out.println("name = " + name);
//        System.out.println("definitionUUID = " + definitionUUID);
//        System.out.println("instanceUUID = " + instanceUUID);
//        System.out.println("fileName = " + fileName);
//        System.out.println("contentMimeType = " + contentMimeType);
        DocumentImpl doc = null;
        try {
            String definition = definitionUUID.toString();
            String instance = instanceUUID != null ? instanceUUID.toString() : "DEFINITION_LEVEL_DOCUMENT";
            FileEntry fileEntry = documentLibrary.addFile(definition, instance, name, fileName, fileContent);
            doc = new DocumentImpl(name);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return doc;
    }

    @Override
    public Document getDocument(String documentId) throws DocumentNotFoundException {
        System.out.println("getDocument");
        Document document = null;
        try {
            DLFileEntry file = documentLibrary.getFileEntry(Long.parseLong(documentId));
            ProcessDefinitionUUID pdUUID = new ProcessDefinitionUUID(file.getFolder().getParentFolder().getName());
            ProcessInstanceUUID piUUID = new ProcessInstanceUUID(file.getFolder().getName());
            document = new DocumentImpl(file.getTitle(), "author", new Date(), new Date(), true, true, file.getVersion(), "", file.getDescription(),
                    "mimetype", file.getSize(), pdUUID, piUUID, "");

            document.setId(String.valueOf(file.getFileEntryId()));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return document;
    }

    @Override
    public void deleteDocument(String documentId, boolean allVersions) throws DocumentNotFoundException {
        System.out.println("deleteDocument");
    }

    @Override
    public byte[] getContent(Document document) throws DocumentNotFoundException {
//        System.out.println("getContent");
//        System.out.println("document.name = " + document.getName());
//        System.out.println("document.id = " + document.getId());
//        System.out.println("document.contentfilename = " + document.getContentFileName());
//        System.out.println("document.getProcessDefinitionUUID = " + document.getProcessDefinitionUUID());
//        System.out.println("document.getProcessInstanceUUID = " + document.getProcessInstanceUUID());
//        String procDef = document.getProcessDefinitionUUID() != null ? document.getProcessDefinitionUUID().toString() : null;
//        String procInst = document.getProcessInstanceUUID() != null ? document.getProcessInstanceUUID().toString() : null;
        byte[] result = documentLibrary.getFileBody(Long.parseLong(document.getId()));
        return result;
    }

    @Override
    public List<Document> getVersionsOfDocument(String documentId) throws DocumentNotFoundException {
        System.out.println("getVersionsOfDocument");
        return null;
    }

    @Override
    public Document createVersion(String documentId, boolean isMajorVersion) throws DocumentationCreationException {
        System.out.println("createVersion");
        return null;
    }

    @Override
    public Document createVersion(String documentId, boolean isMajorVersion, String fileName, String mimeType, byte[] content) throws DocumentationCreationException {
        System.out.println("createVersion3");
//        System.out.println("documentId = " + documentId);
//        System.out.println("isMajorVersion = " + isMajorVersion);
//        System.out.println("fileName = " + fileName);
//        System.out.println("mimeType = " + mimeType);
//        System.out.println("content = " + content.length);
        Document document = null;
        try {
            DLFileEntry file = documentLibrary.getFileEntry(Long.valueOf(documentId).longValue());
            file.setDescription(fileName);
            DLFileEntry result = documentLibrary.updateFileEntry(file);


            ProcessDefinitionUUID pdUUID = new ProcessDefinitionUUID(result.getFolder().getParentFolder().getName());
            ProcessInstanceUUID piUUID = new ProcessInstanceUUID(result.getFolder().getName());
            document = new DocumentImpl(file.getTitle(), "author", new Date(), new Date(), true, true, file.getVersion(), "", file.getDescription(),
                    "mimetype", file.getSize(), pdUUID, piUUID, "");

            document.setId(String.valueOf(result.getFileEntryId()));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return document;
    }

    @Override
    public SearchResult search(DocumentSearchBuilder builder, int fromResult, int maxResults) {
        System.out.println("search");
////        File x = new File("builder.xml");
//        try {
//            FileOutputStream fos = new FileOutputStream(x);
//            fos.write(builder.toString().getBytes());
//            fos.close();
//        } catch (Exception ex) {
//            ex.printStackTrace();
//        }

        HashMap<DocumentIndex, DocumentCriterion> crits = new HashMap<DocumentIndex, DocumentCriterion>();
        for (Object o : builder.getQuery()) {
            if (o instanceof String) {
            } else if (o instanceof DocumentCriterion) {
                DocumentCriterion dc = (DocumentCriterion) o;
                crits.put(dc.getField(), dc);
//                System.out.println("crit = " + dc.getField() + " = " + dc.getValue());
            }
        }
        String procDefString = crits.containsKey(DocumentIndex.PROCESS_DEFINITION_UUID) ? crits.get(DocumentIndex.PROCESS_DEFINITION_UUID).getValue().toString() : null;
        String procInstString = crits.containsKey(DocumentIndex.PROCESS_INSTANCE_UUID) ? crits.get(DocumentIndex.PROCESS_INSTANCE_UUID).getValue().toString() : null;

        ProcessInstanceUUID procInst = procInstString != null ? new ProcessInstanceUUID(procInstString) : null;
        ProcessDefinitionUUID procDef = procDefString != null ? new ProcessDefinitionUUID(procDefString) : null;
        if (procDef == null && procInst != null) {
            procDef = procInst.getProcessDefinitionUUID();
            procDefString = procDef.toString();
        }

        String attachmentName = crits.containsKey(DocumentIndex.NAME) ? crits.get(DocumentIndex.NAME).getValue().toString() : null;

        List<DLFileEntry> files = new ArrayList<DLFileEntry>();
        try {
            if (attachmentName == null) {
                files = documentLibrary.getProcessFiles(procDefString, procInstString);
            } else {
                files.add(documentLibrary.getProcessFile(procDefString, procInstString, attachmentName));
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        List<Document> list = new ArrayList<Document>();
        if (!files.isEmpty()) {
            for (DLFileEntry file : files) {
//                System.out.println("document = " + file.getFileEntryId() + ", " + file.getTitle());
//                Document document = new DocumentImpl(file.getTitle(), file.getDescription(), "null", file.getSize());
                Document document = new DocumentImpl(file.getTitle(), "author", new Date(), new Date(), true, true, file.getVersion(), "", file.getDescription(),
                        "mimetype", file.getSize(), procDef, procInst, "");
                document.setId(String.valueOf(file.getFileEntryId()));
                list.add(document);
            }
            return new SearchResult(list, list.size());
        } else {
            return new SearchResult(list, 0);
        }
    }

    @Override
    public void clear() throws DocumentNotFoundException {
        System.out.println("clear");
    }

    @Override
    public void attachDocumentTo(ProcessDefinitionUUID processDefinitionUUID, ProcessInstanceUUID processInstanceUUID, String documentId) throws DocumentNotFoundException {
        System.out.println("attachDocumentTo2");
    }

    public Document createDocument(String string, ProcessDefinitionUUID pduuid) throws DocumentationCreationException, DocumentAlreadyExistsException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Document createDocument(String string, ProcessDefinitionUUID pduuid, ProcessInstanceUUID piuuid) throws DocumentationCreationException, DocumentAlreadyExistsException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Document createDocument(String string, ProcessDefinitionUUID pduuid, String string1, String string2, byte[] bytes) throws DocumentationCreationException, DocumentAlreadyExistsException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Document createDocument(String string, ProcessDefinitionUUID pduuid, ProcessInstanceUUID piuuid, String string1, String string2, byte[] bytes, String string3, Date date, Date date1) throws DocumentationCreationException, DocumentAlreadyExistsException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Document createMetaDocument(ProcessDefinitionUUID pduuid, String string, String string1, String string2, byte[] bytes) throws DocumentationCreationException, DocumentAlreadyExistsException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Document createMetaDocument(ProcessDefinitionUUID pduuid, String string, String string1, String string2, byte[] bytes, String string3, Date date, Date date1) throws DocumentationCreationException, DocumentAlreadyExistsException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public List<Document> getMetaDocuments(ProcessDefinitionUUID pduuid) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public Document createVersion(String string, boolean bln, String string1, String string2, byte[] bytes, String string3, Date date, Date date1) throws DocumentationCreationException {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public List<Document> getDocuments(ProcessInstanceUUID piuuid, int i, int i1) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public List<Document> getDocuments(ProcessInstanceUUID piuuid, String string, int i, int i1) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public long getNbOfDocuments(ProcessInstanceUUID piuuid, String string) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public List<Document> getDocuments(ProcessDefinitionUUID pduuid, String string, int i, int i1) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public List<Document> getDocumentsOfProcessDefinitionWithoutInstances(ProcessDefinitionUUID pduuid, int i, int i1) {
        throw new UnsupportedOperationException("Not supported yet.");
    }

    public void deleteDocuments(ProcessDefinitionUUID pduuid) throws DocumentNotFoundException {
        throw new UnsupportedOperationException("Not supported yet.");
    }
}
